package com.itheima.reggie.controller;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.itheima.reggie.common.R;
import com.itheima.reggie.entity.Category;
import com.itheima.reggie.entity.Dish;
import com.itheima.reggie.dto.DishDto;
import com.itheima.reggie.entity.DishFlavor;
import com.itheima.reggie.service.CategoryService;
import com.itheima.reggie.service.DishFlavorService;
import com.itheima.reggie.service.DishService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.websocket.server.PathParam;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 菜品和菜品口味管理
 */
@Slf4j
@RestController
@RequestMapping("/dish")
public class DishController {
    @Autowired
    private DishFlavorService dishFlavorService;
    @Autowired
    private DishService dishService;
    @Autowired
    private CategoryService categoryService;

    /**
     * 新增菜品方法
     *
     * @param dishDto
     * @return
     */
    @PostMapping
    public R<String> save(@RequestBody DishDto dishDto) {
        log.info(dishDto.toString());
        //新增菜品（复合信息）
        dishService.saveWithFlavor(dishDto);
        return R.success("新增菜品成功");
    }

    /**
     * 菜品分页查询
     *
     * @param page
     * @param pageSize
     * @param name
     * @return
     */
    @GetMapping("/page")
    public R<Page> page(int page, int pageSize, String name) {
        //分页构造器
        Page<Dish> pageInf = new Page<>(page, pageSize);
        //优化1 分页构造器2
        Page<DishDto> pageInf2 = new Page<>();
        //条件对象
        LambdaQueryWrapper<Dish> lqw = new LambdaQueryWrapper();
        lqw.like(name != null, Dish::getName, name);
        lqw.orderByDesc(Dish::getUpdateTime);
        dishService.page(pageInf, lqw);

        //优化2 将第一个分页构造器拷贝到第二个里面
        BeanUtils.copyProperties(pageInf, pageInf2, "records");
        //优化3 获取第一个分页构造器中的集合属性：页面展示的查询数据列表
        List<Dish> records = pageInf.getRecords();
        //优化4 处理数据
        List<DishDto> dtoList = records.stream().map((item) -> {   //item 就是集合里的对象 Dish
            //a.先把对象Dish基本属性拷贝到DishDot中
            DishDto dto = new DishDto();
            BeanUtils.copyProperties(item, dto);
            //b.然后获取Dish(item)对象中的分类id
            Long categoryId = item.getCategoryId();
            //c.根据id查 分类对象
            Category category = categoryService.getById(categoryId);
            //e.做个简单判断
            if (category != null) {
                //d.获取分类对象的名字 并设置给对象dto
                String categoryName = category.getName();
                dto.setCategoryName(categoryName);
            }
            //f.返回设置后的对象
            return dto;
            //g.返回成新的集合
        }).collect(Collectors.toList());

        //优化5. 对分页构造器2中的records属性进行赋值
        pageInf2.setRecords(dtoList);

        return R.success(pageInf2);
    }


    /**
     * 根据id查询菜品信息和对应的口味信息
     *
     * @param id
     * @return
     */
    @GetMapping("/{id}")
    public R<DishDto> get(@PathVariable Long id) {
        DishDto dishDto = dishService.getByIdWithFlavor(id);
        return R.success(dishDto);
    }

    /**
     * 修改菜品
     *
     * @param dishDto
     * @return
     */
    @PutMapping
    public R<String> updateWithFlavor(@RequestBody DishDto dishDto) {
        dishService.updateWithFlavor(dishDto);
        return R.success("修改菜品成功");
    }

    /**
     * 批量删除
     *
     * @param ids
     * @return
     */
    @DeleteMapping
    public R<String> delete(@RequestParam List<Long> ids) {
        log.info("ids:{}", ids);
        dishService.delete(ids);
        return R.success("删除成功");
    }

    /**
     * 根据菜品分类id查询菜品集合
     *
     * @param dish
     * @return
     */
    @GetMapping("/list") //Request URL: http://localhost:8080/dish/list?categoryId=1397844263642378242
    public R<List<DishDto>> list(Dish dish) {
        //虽然请求是id 但是我们用实体类接收，后期万一改成其他属性 也可以拓展
        LambdaQueryWrapper<Dish> lqw = new LambdaQueryWrapper();
        lqw.eq(dish.getCategoryId() != null, Dish::getCategoryId, dish.getCategoryId());
        //注意，查询出来的菜品，状态肯定是在售状态
        lqw.eq(Dish::getStatus, 1);
        //添加排序条件
        lqw.orderByAsc(Dish::getSort).orderByDesc(Dish::getUpdateTime);
        List<Dish> list = dishService.list(lqw);

        //优化： 因为前端页面展示不全 所以要返回DishDto复合类 里面包含categoryName 用于展示
        List<DishDto> dishDtoList = list.stream().map((item) -> {
            DishDto dishDto = new DishDto();
            BeanUtils.copyProperties(item, dishDto);
            /*
                 还需要获取菜品分类名 和 口味列表， 怎么查？
                1. dish里数据有categoryId，获取到id后
                2. 获取Category对象，然后 获取对象的name属性
                3.赋值给dishDto，并返回
                a.dish里面只有id 没有口味信息 但是DishFlavor包含dishId
                b.DishFlavor根据dishId查询口味返回集合
             */
            //菜品名
            Long categoryId = item.getCategoryId(); //菜品id
            Category category = categoryService.getById(categoryId); //菜品对象
            if (category != null) {
                String categoryName = category.getName(); //菜品名
                dishDto.setCategoryName(categoryName); //赋值 完成菜品名拷贝操作
            }
            //口味列表：DishFlavor
            Long dishId = item.getId();//dishId
            LambdaQueryWrapper<DishFlavor> lqw2 = new LambdaQueryWrapper<>();
            lqw2.in(DishFlavor::getDishId, dishId);
            List<DishFlavor> dishFlavors = dishFlavorService.list(lqw2); //查询到的口味集合
            //设置
            dishDto.setFlavors(dishFlavors);
            return dishDto;
        }).collect(Collectors.toList());

        return R.success(dishDtoList);
    }

    /**
     * 批量修改状态
     * @param s
     * @param ids
     * @return
     */
    @PostMapping(value = "/status/{s}")  //  "/status/1"  "/status/0"
    public R<String> updateS(@PathVariable int s, @RequestParam List<Long> ids) {
        log.info("ids:{}", ids); //传进来集合ids
        log.info("s==>", s);

        LambdaQueryWrapper<Dish> lqw = new LambdaQueryWrapper<>();
        lqw.in(Dish::getId, ids);
        List<Dish> list = dishService.list(lqw);
        List<Dish> dishList = list.stream().map((dish) -> {
            dish.setStatus(s);
            return dish;
        }).collect(Collectors.toList());
        dishService.updateBatchById(dishList);

        return R.success("修改成功");
    }

}
